package net.uofitorn.lunchlocationtrackerclient;

import android.os.Bundle;
import android.app.Activity;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.*;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class MainActivity extends Activity {

    private Button openConnectionButton;
    private Button sendInformationButton;
    private Button closeConnectionButton;
    private EditText editText;
    private TextView statusText;
    private boolean connected = false;
    private static final String TAG = "LunchTracker";
    private Handler childHandler;

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Bundle bundle = msg.getData();
            int command = bundle.getInt("command");
            switch(command) {
                case 0:
                    statusText.setText("Connected to server.");
                    break;
                case 1:
                    String msgFromServer = bundle.getString("message");
                    statusText.setText(msgFromServer);
                    break;
                case 2:
                    statusText.setText("Disconnected from server");
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        openConnectionButton = (Button)findViewById(R.id.button);
        closeConnectionButton = (Button) findViewById(R.id.closeButton);
        sendInformationButton = (Button) findViewById(R.id.button2);
        statusText = (TextView) findViewById(R.id.textView2);
        statusText.setText("");
        editText = (EditText) findViewById(R.id.editText2);

        Thread cThread = new Thread(new ClientThread(MainActivity.this));
        cThread.start();

        sendInformationButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Message msg = childHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("command", 1);
                bundle.putString("message", editText.getText().toString());
                msg.setData(bundle);
                childHandler.sendMessage(msg);
            }
        });

        openConnectionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Message msg = childHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("command", 0);
                msg.setData(bundle);
                childHandler.sendMessage(msg);
            }
        });

        closeConnectionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Message msg = childHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("command", 2);
                msg.setData(bundle);
                childHandler.sendMessage(msg);
            }
        });
    }

    public class ClientThread implements Runnable {

        Activity activity;
        String toSend = "Temp message";
        InetAddress serverAddr;
        Socket socket;

        public ClientThread(Activity activity) {
            this.activity = activity;
        }

        public void run() {
            try {
                Looper.prepare();
                childHandler = new Handler() {
                    public void handleMessage(Message msg) {
                        Bundle bundle = msg.getData();
                        int command = bundle.getInt("command");
                        Log.i(TAG, "Received command: " + command);
                        switch(command) {
                            case 0:
                                connectToServer();
                                break;
                            case 1:
                                String msgToSend = bundle.getString("message");
                                sendAndReceiveMessage(msgToSend);
                                break;
                            case 2:
                                closeConnection();
                                break;
                        }
                    }
                };
                Looper.loop();
            } catch (Exception e) {
                Log.e(TAG, "Caught Exception in worker thread message loop");
            }
        }

        public void connectToServer() {
            try {
                serverAddr = InetAddress.getByName("208.78.100.124");
                socket = new Socket(serverAddr, 3000);
                connected = true;
                Message msg = handler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("command", 0);
                msg.setData(bundle);
                handler.sendMessage(msg);
            } catch (Exception e) {
                Log.e(TAG, "Caught exception connecting to server");
            }
        }

        public void sendAndReceiveMessage(String msgToSend) {
            try {
                PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                out.println(msgToSend);
                out.println(".");
                BufferedReader in = new BufferedReader (new InputStreamReader(socket.getInputStream()));
                final String msgFromServer = in.readLine();
                Message msg = handler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("command", 1);
                bundle.putString("message", msgFromServer);
                msg.setData(bundle);
                handler.sendMessage(msg);
                Log.i(TAG, "Received message from server: " + msgFromServer);
            } catch (Exception e) {
                Log.e(TAG, "Caught exception sending or receiving message");
            }
        }

        public void closeConnection() {
            try {
                socket.close();
                connected = false;
                Message msg = handler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("command", 2);
                msg.setData(bundle);
                handler.sendMessage(msg);
            } catch (Exception e) {
                Log.e(TAG, "Caught exception closing socket");
            }
            connected = false;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}
